@inline function date2rata(caldate::Date)
    return date2epochdays(caldate) - 365
end

@inline function rata2date(rata::Int64)
    return epochdays2date(rata + 365)
end

# supported span of dates
const EPOCH1950 = Date("1950-01-01")
const EPOCH2082 = Date("2086-01-01") # two msbs are zero forall in range
const EPOCH2241 = Date("2241-01-01") # the msb is zero forall in range

const EPOCH1970 = Date("1970-01-01")
const EPOCH2116 = Date("2116-01-01") # two msbs are zero forall in range
const EPOCH2261 = Date("2261-01-01") # thhe msb is zero forall in range

if NANOTIME_FRAME == 0
  # with the signbit free
  const FIRST_DATE = EPOCH1950
  const FINAL_DATE = EPOCH2241
elseif NANOTIME_FRAME == 1
  # with the signbit free
  const FIRST_DATE = EPOCH1970
  const FINAL_DATE = EPOCH2261
elseif NANOTIME_FRAME == 2
  # with the sign and the oveflow bits free
  const FIRST_DATE = EPOCH1970
  const FINAL_DATE = EPOCH2116
end

const FIRST_VALID_YEAR = year(FIRST_DATE)
const FINAL_VALID_YEAR = year(FINAL_DATE) - 1
const FIRST_VALID_YEAR_AS_MONTHS = FIRST_VALID_YEAR * MONTHS_PER_YEAR
const FINAL_VALID_YEAR_AS_MONTHS = FINAL_VALID_YEAR * MONTHS_PER_YEAR

const RATAFIRST = date2rata(FIRST_DATE)
const RATAFINAL = date2rata(FINAL_DATE)

@inline function rataguard(rata::Int64)
    (RATAFIRST <= rata <= RATAFINAL) && return nothing
    throw(ErrorException("date must be in $(FIRST_DATE)..$(FINAL_DATE)."))
end

@inline function dateguard(date::Date)
    (FIRST_DATE <= date <= FINAL_DATE) && return nothing
    throw(ErrorException("date must be in $(FIRST_DATE)..$(FINAL_DATE)."))
end

@inline function yearguard(year::T) where T<:Integer
    (FIRST_VALID_YEAR <= year <= FINAL_VALID_YEAR) && return nothing
    throw(ErrorException("year $(year) is not supported by NanoTimes"))
end
